/*
 * AddressCodec.java
 * Copyright: Tsingsoft (c) 2015
 * Company: 北京清软创新科技有限公司
 */
package org.liang.email4j.helper;

import java.io.UnsupportedEncodingException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.mail.internet.MimeUtility;

/**
 * 邮箱地址编译器.
 * 
 * <pre>
 * 提供对邮箱地址进行编码、解码行为
 * </pre>
 * 
 * @author L.Yang
 * @version 1.0, 2015年8月10日
 */
public class AddressCodec {

    /** 定义一个邮箱地址的正则表达式：姓名<'邮箱'>. */
    private static final Pattern PATTERN = Pattern.compile("(.+)(<.+@.+..+>)");

    /** 邮箱地址 名称前缀. */
    private static final String START = "<";

    /** 邮箱地址 名称后缀. */
    private static final String END = ">";

    /** 邮件地址编码类型 : ENCODE, DECODE. */
    private enum CodecType {
        /** 编码. */
        ENCODE,
        /** 解码. */
        DECODE
    }

    /**
     * 编码邮箱地址.
     * 
     * @param address
     *            '姓名<'邮箱'>' 格式的邮箱地址
     * @return 编码后的地址
     */
    public static final String encode(String address) {
        return codec(CodecType.ENCODE, address);
    }

    /**
     * 解码邮箱地址.
     * 
     * @param address 地址密文
     * @return '姓名<'邮箱'>' 格式的邮箱地址
     */
    public static final String decode(String address) {
        return codec(CodecType.DECODE, address);
    }

    /**
     * 编码邮箱地址.
     * 
     * @param codecType
     *            编码类型 见枚举 {@link CodecType}
     * @param address
     *            邮件地址
     * @return 编码后的邮件地址
     */
    private static String codec(CodecType codecType, String address) {
        Matcher addressMatcher = PATTERN.matcher(address);
        // 需要对满足匹配条件的邮箱地址进行 UTF-8 编码，否则姓名将出现中文乱码
        if (addressMatcher.find()) {
            try {
                if (codecType == CodecType.ENCODE) {
                    address = MimeUtility.encodeText(addressMatcher.group(1), "UTF-8", "B")
                              + addressMatcher.group(2);
                } else {
                    address = MimeUtility.decodeText(addressMatcher.group(1))
                              + addressMatcher.group(2);
                }
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException("错误：邮箱地址编解码出错！", e);
            }
        }
        return address;
    }

    /**
     * 获取邮件地址格式中的名称.
     * 
     * <pre>
     * 如果没有则返回空。
     * 邮箱地址格式: 姓名<'邮箱'>' 
     * </pre>
     * 
     * @param address
     *            邮箱地址
     * @return 地址中的名称
     */
    public static String getName(String address) {
        Matcher addressMatcher = PATTERN.matcher(address);
        if (addressMatcher.find()) {
            int m = address.indexOf(START);
            return address.substring(0, m);
        }
        return "";
    }

    /**
     * 获取邮件地址格式中的邮箱.
     * 
     * <pre>
     * 邮箱地址格式: 姓名<'邮箱'>' 
     * </pre>
     * 
     * @param address
     *            邮箱地址
     * @return 地址中的邮箱
     */
    public static String getEmail(String address) {
        Matcher addressMatcher = PATTERN.matcher(address);
        if (addressMatcher.find()) {
            int m = address.indexOf(START);
            int n = address.indexOf(END);
            return address.substring(m + 1, n);
        }
        return address;
    }
}
